package main

import (
	"fmt"
	"os"
	"reflect"
	"strconv"
	"strings"
)

type order struct {
	ordId      int
	customerId int
}

type employee struct {
	name    string
	id      int
	address string
	salary  int
	country string
}

//学习其他学员,使用append
func createQuery_(q interface{}) {
	t := reflect.TypeOf(q)
	v := reflect.ValueOf(q)
	if t.Kind() != reflect.Struct {
		fmt.Fprintln(os.Stdout, "unsupported type")
		return
	}
	var sqlParams []string
	for i := 0; i < v.NumField(); i++ {
		switch vv := v.Field(i).Kind(); vv {
		case reflect.Int:
			sqlParams = append(sqlParams, strconv.Itoa(int(v.Field(i).Int())))
		case reflect.String:
			sqlParams = append(sqlParams, "\""+v.Field(i).String()+"\"")
		default:
			fmt.Fprintln(os.Stdout, "unsupported type")
			return
		}
	}
	fmt.Fprintf(os.Stdout, "insert into %s values(%s)\n", t.Name(), strings.Join(sqlParams, ", "))
	return
}

func createQuery(q interface{}) {
	if reflect.TypeOf(q).Kind() != reflect.Struct {
		fmt.Println("unsupported type")
		return
	}
	t := reflect.TypeOf(q)
	tn := t.Name()
	//无sql字段
	sql := fmt.Sprintf("insert into %s values(", tn)
	//有sql字段
	sqlF := fmt.Sprintf("insert into %s (", tn)
	for i := 0; i < t.NumField(); i++ {
		vn := t.Field(i).Name
		if i == 0 {
			sqlF = fmt.Sprintf("%s`%s`", sqlF, vn)
		} else if i == (t.NumField() - 1) {
			sqlF = fmt.Sprintf("%s, `%s`) values(", sqlF, vn)
		} else {
			sqlF = fmt.Sprintf("%s, `%s`", sqlF, vn)
		}
	}
	v := reflect.ValueOf(q)
	for i := 0; i < v.NumField(); i++ {
		vt := v.Field(i).Kind()
		switch vt {
		case reflect.Int:
			if i == 0 {
				sql = fmt.Sprintf("%s%d", sql, v.Field(i).Int())
				sqlF = fmt.Sprintf("%s%d", sqlF, v.Field(i).Int())
			} else {
				sql = fmt.Sprintf("%s, %d", sql, v.Field(i).Int())
				sqlF = fmt.Sprintf("%s, %d", sqlF, v.Field(i).Int())
			}
		case reflect.String:
			if i == 0 {
				sql = fmt.Sprintf("%s\"%s\"", sql, v.Field(i).String())
				sqlF = fmt.Sprintf("%s\"%s\"", sqlF, v.Field(i).String())
			} else {
				sql = fmt.Sprintf("%s, \"%s\"", sql, v.Field(i).String())
				sqlF = fmt.Sprintf("%s, \"%s\"", sqlF, v.Field(i).String())
			}
		default:
			fmt.Println("unsupported type")
			return
		}
	}
	sql = fmt.Sprintf("%s)", sql)
	fmt.Println(sql)
	//sqlF = fmt.Sprintf("%s)", sqlF)
	//fmt.Println(sqlF)
	return
}

func main() {
	o := order{
		ordId:      456,
		customerId: 56,
	}
	createQuery(o)

	e := employee{
		name:    "Naveen",
		id:      565,
		address: "Coimbatore",
		salary:  90000,
		country: "India",
	}
	createQuery(e)
	createQuery_(e)

	i := 90
	createQuery(i)
}
